﻿///* Created on 2017.3.25
// *
// * @author: jia
// */
//
//#pragma once
//#include "objectpool.h"
//#include <string>
//#include <vector>
//
//typedef unsigned char byte;
//typedef unsigned char byte;
//typedef signed char int8;
//typedef unsigned char uint8;
//typedef short int16_t;
//typedef short int16;
//typedef unsigned short uint16_t;
//typedef uint16_t uint16;
//typedef signed char sbyte;
//typedef signed int int32;
//typedef unsigned int uint32;
//typedef unsigned int uint32;
//typedef long long int64;
//typedef unsigned long long uint64;
//
///*
//    小端时返回true
//*/
//bool isPlatformLittleEndian()
//{
//   int n = 1;
//   return *((char*)&n) ? true : false;
//}
//
//static bool IS_PLATFORM_LITTLE_ENDIAN = isPlatformLittleEndian();
//
//namespace MemoryStreamConverter
//{
//    template<size_t T>
//    inline void convert(char *val)
//    {
//        std::swap(*val, *(val + T - 1));
//        convert<T - 2>(val + 1);
//    }
//
//    template<> inline void convert<0>(char *) {}
//    template<> inline void convert<1>(char *) {}            // ignore central byte
//
//    template <typename T>
//    inline void apply(T *val)
//    {
//        convert<sizeof(T)>((char *)(val));
//    }
//
//    inline void convert(char *val, size_t size)
//    {
//        if (size < 2)
//            return;
//
//        std::swap(*val, *(val + size - 1));
//        convert(val + 1, size - 2);
//    }
//}
//
//template <typename T>
//inline void EndianConvert(T &val)
//{
//    if (!IS_PLATFORM_LITTLE_ENDIAN)
//        MemoryStreamConverter::apply<T>(&val);
//}
//
//template <typename T>
//inline void EndianConvertReverse(T &val)
//{
//    if (IS_PLATFORM_LITTLE_ENDIAN)
//        MemoryStreamConverter::apply<T>(&val);
//}
//
//template <typename T> void EndianConvert(T *); // will generate link error
//template <typename T> void EndianConvertReverse(T *); // will generate link error
//
//inline void EndianConvert(uint8 &) {}
//inline void EndianConvert(int8 &) {}
//inline void EndianConvertReverse(uint8 &) {}
//inline void EndianConvertReverse(int8 &) {}
//
//
//// TODO: 继承exception， 添加__FILE__,__LINE__,__FUNCTION__信息
//class MemoryStreamException
//{
//    public:
//        MemoryStreamException(bool _add, size_t _pos, size_t _esize, size_t _size)
//            : _m_add(_add), _m_pos(_pos), _m_esize(_esize), _m_size(_size)
//        {
//            PrintPosError();
//        }
//
//        void PrintPosError() const
//        {
//            printf ("Attempted to %1% in MemoryStream (pos:%2%  size: %3%).\n" ,
//                (_m_add ? "put" : "get") , _m_pos , _m_size);
//        }
//    private:
//        bool        _m_add;
//        size_t      _m_pos;
//        size_t      _m_esize;
//        size_t      _m_size;
//};
//
///*
//    二进制数据流模块
//    能够将一些基本类型序列化(writeXXX)成二进制流同时也提供了反序列化(readXXX)等操作
//*/
//class MemoryStream : KBEObjectPool<MemoryStream>
//{
//public:
//    const static size_t DEFAULT_SIZE = 0x1000;
//
//    union PackFloatXType
//    {
//        float fv;
//        uint32 uv;
//        int iv;
//    };
//public:
//    MemoryStream() : rpos_(0),
//                     wpos_(0)
//    {
//        data_.reserve(DEFAULT_SIZE);
//    }
//
//    virtual ~MemoryStream()
//    {
//        clear(true);
//    }
//
//private:
//    size_t rpos_;
//    size_t wpos_;
//    std::vector<uint8> data_;
//
//public:
//    // 把自己放回缓冲池
//    void reclaimObject()
//    {
//        clear(false);
//        KBEObjectPool<MemoryStream>::reclaimObject(this);
//    }
//
//    const uint8 *data() const
//    {
//        return &data_[0];
//    }
//
//    void clear(bool clearData)
//    {
//        if(clearData)
//            data_.clear();
//        rpos_ = wpos_ = 0;
//    }
//
//    size_t opsize() const { return rpos() >= wpos() ? 0 : wpos() - rpos(); }
//
//    size_t rpos() const { return rpos_; }
//
//    size_t rpos(int rpos)
//    {
//        if (rpos < 0)
//            rpos = 0;
//
//        rpos_ = rpos;
//        return rpos_;
//    }
//
//    size_t wpos() const { return wpos_; }
//
//    size_t wpos(int wpos)
//    {
//        if (wpos < 0)
//            wpos = 0;
//
//        wpos_ = wpos;
//        return wpos_;
//    }
//
//
//
//
//    template <typename T>
//    T read()
//    {
//        T r = read<T>(rpos_);
//        rpos_ += sizeof(T);
//        return r;
//    }
//
//    template <typename T>
//    T read(size_t pos) const
//    {
//        if (sizeof(T) > opsize())
//            throw MemoryStreamException(false, pos, sizeof(T), opsize());
//
//		T val = *((T const*)&data_[pos]);
//        EndianConvert(val);
//        return val;
//    }
//
//    void read(uint8 *dest, size_t len)
//    {
//        if (len > opsize())
//            throw MemoryStreamException(false, rpos_, len, opsize());
//
//		memcpy(dest, &data_[rpos_], len);
//        rpos_ += len;
//    }
//
//
//
//
//
//
//
//
//
//
//
//	
//
//
//
//  
//	 MemoryStream &operator>>(int8 &value)
//    {
//        value = read<int8>();
//        return *this;
//    }
//
//
// 
//	 MemoryStream &operator>>(int16 &value)
//    {
//        value = read<int16>();
//        return *this;
//    }
//
//
//
//	  MemoryStream &operator>>(int32 &value)
//    {
//        value = read<int32>();
//        return *this;
//    }
//
//
//
//
//	 MemoryStream &operator>>(int64 &value)
//    {
//        value = read<int64>();
//        return *this;
//    }
//
//
//
//
//
//
//
//    byte readUint8()
//    {
//        return datas_[rpos++];
//    }
//
//    uint16 readUint16()
//    {
//        rpos += 2;
//        return BitConverter.ToUInt16(datas_, rpos - 2);
//    }
//
//    uint32 readUint32()
//    {
//        rpos += 4;
//        return BitConverter.ToUInt32(datas_, rpos - 4);
//    }
//
//    uint64 readUint64()
//    {
//        rpos += 8;
//        return BitConverter.ToUInt64(datas_, rpos - 8);
//    }
//
//    float readFloat()
//    {
//        rpos += 4;
//        return BitConverter.ToSingle(datas_, rpos - 4);
//    }
//
//    double readDouble()
//    {
//        rpos += 8;
//        return BitConverter.ToDouble(datas_, rpos - 8);
//    }
//
//    std::string readString()
//    {
//        int offset = rpos;
//        while (datas_[rpos++] != 0)
//        {
//        }
//
//        return _converter.GetString(datas_, offset, rpos - offset - 1);
//    }
//
//    byte* readBlob()
//    {
//        uint32 size = readUint32();
//        byte[] buf = new byte[size];
//
//        Array.Copy(datas_, rpos, buf, 0, size);
//        rpos += (int)size;
//        return buf;
//    }
//
//    Vector2 readPackXZ()
//    {
//        PackFloatXType xPackData;
//        PackFloatXType zPackData;
//
//        xPackData.fv = 0f;
//        zPackData.fv = 0f;
//
//        xPackData.uv = 0x40000000;
//        zPackData.uv = 0x40000000;
//
//        byte v1 = readUint8();
//        byte v2 = readUint8();
//        byte v3 = readUint8();
//
//        uint32 data = 0;
//        data |= ((uint32)v1 << 16);
//        data |= ((uint32)v2 << 8);
//        data |= (uint32)v3;
//
//        xPackData.uv |= (data & 0x7ff000) << 3;
//        zPackData.uv |= (data & 0x0007ff) << 15;
//
//        xPackData.fv -= 2.0f;
//        zPackData.fv -= 2.0f;
//
//        xPackData.uv |= (data & 0x800000) << 8;
//        zPackData.uv |= (data & 0x000800) << 20;
//
//        Vector2 vec = new Vector2(xPackData.fv, zPackData.fv);
//        return vec;
//    }
//
//    float readPackY()
//    {
//        PackFloatXType yPackData;
//        yPackData.fv = 0f;
//        yPackData.uv = 0x40000000;
//
//        uint16 data = readUint16();
//
//        yPackData.uv |= ((uint32)data & 0x7fff) << 12;
//        yPackData.fv -= 2f;
//        yPackData.uv |= ((uint32)data & 0x8000) << 16;
//
//        return yPackData.fv;
//    }
//
//
//    void writeInt8(sbyte v)
//    {
//        datas_[wpos++] = (byte)v;
//    }
//
//    void writeInt16(int16 v)
//    {
//        writeInt8((sbyte)(v & 0xff));
//        writeInt8((sbyte)(v >> 8 & 0xff));
//    }
//
//    void writeInt32(int32 v)
//    {
//        for (int i = 0; i < 4; i++)
//            writeInt8((sbyte)(v >> i * 8 & 0xff));
//    }
//
//    void writeInt64(int64 v)
//    {
//        byte[] getdata = BitConverter.GetBytes(v);
//        for (int i = 0; i < getdata.Length; i++)
//        {
//            datas_[wpos++] = getdata[i];
//        }
//    }
//
//    void writeUint8(byte v)
//    {
//        datas_[wpos++] = v;
//    }
//
//    void writeUint16(uint16 v)
//    {
//        writeUint8((byte)(v & 0xff));
//        writeUint8((byte)(v >> 8 & 0xff));
//    }
//
//    void writeUint32(uint32 v)
//    {
//        for (int i = 0; i < 4; i++)
//            writeUint8((byte)(v >> i * 8 & 0xff));
//    }
//
//    void writeUint64(uint64 v)
//    {
//        byte[] getdata = BitConverter.GetBytes(v);
//        for (int i = 0; i < getdata.Length; i++)
//        {
//            datas_[wpos++] = getdata[i];
//        }
//    }
//
//    void writeFloat(float v)
//    {
//        byte[] getdata = BitConverter.GetBytes(v);
//        for (int i = 0; i < getdata.Length; i++)
//        {
//            datas_[wpos++] = getdata[i];
//        }
//    }
//
//    void writeDouble(double v)
//    {
//        byte[] getdata = BitConverter.GetBytes(v);
//        for (int i = 0; i < getdata.Length; i++)
//        {
//            datas_[wpos++] = getdata[i];
//        }
//    }
//
//    void writeBlob(byte[] v)
//    {
//        uint32 size = (uint32)v.Length;
//        if (size + 4 > space())
//        {
//            Dbg.ERROR_MSG("memorystream::writeBlob: no free!");
//            return;
//        }
//
//        writeUint32(size);
//
//        for (uint32 i = 0; i < size; i++)
//        {
//            datas_[wpos++] = v[i];
//        }
//    }
//
//    void writeString(std::string v)
//    {
//        if (v.Length > space())
//        {
//            Dbg.ERROR_MSG("memorystream::writeString: no free!");
//            return;
//        }
//
//        byte[] getdata = System.Text.Encoding.ASCII.GetBytes(v);
//        for (int i = 0; i < getdata.Length; i++)
//        {
//            datas_[wpos++] = getdata[i];
//        }
//
//        datas_[wpos++] = 0;
//    }
//
//
//    void append(byte[] datas, uint32 offset, uint32 size)
//    {
//        uint32 free = space();
//        if (free < size)
//        {
//            byte[] newdatas = new byte[datas_.Length + size * 2];
//            Array.Copy(datas_, 0, newdatas, 0, wpos);
//            datas_ = newdatas;
//        }
//
//        Array.Copy(datas, offset, datas_, wpos, size);
//        wpos += (int)size;
//    }
//
//
//    void readSkip(uint32 v)
//    {
//        rpos += (int)v;
//    }
//
//
//    uint32 space()
//    {
//        return (uint32)(data().Length - wpos);
//    }
//
//
//
//
//
//    bool readEOF()
//    {
//        return (BUFFER_MAX - rpos) <= 0;
//    }
//
//
//    void done()
//    {
//        rpos = wpos;
//    }
//
//
//
//
//
//    byte[] getbuffer()
//    {
//        byte[] buf = new byte[length()];
//        Array.Copy(data(), rpos, buf, 0, length());
//        return buf;
//    }
//
//
//    std::string toString()
//    {
//        std::string s = "";
//        int ii = 0;
//        byte[] buf = getbuffer();
//
//        for (int i = 0; i < buf.Length; i++)
//        {
//            ii += 1;
//            if (ii >= 200)
//            {
//                // MyDebug.Dbg.Log(s);
//                s = "";
//                ii = 0;
//            }
//
//            s += buf[i];
//            s += " ";
//        }
//
//        // MyDebug.Dbg.Log(s);
//        return s;
//    }
//};
